package com.iretailer.report.analyze.device.face;

import com.iretailer.report.analyze.commonModel.InOutMetric;
import com.iretailer.report.analyze.commonModel.PassengerFlowModel;
import com.iretailer.report.analyze.commonUtil.ResponeResultType;
import com.iretailer.report.analyze.device.DeviceCommon;
import com.iretailer.report.analyze.device.face.faceapi.FaceApi;
import com.iretailer.report.analyze.device.face.horizon.model.*;
import com.iretailer.report.analyze.flow.FlowInsert;
import com.iretailer.report.model.Categories;
import com.iretailer.report.model.Device;
import com.iretailer.report.model.GenderAge;
import com.iretailer.report.service.CategoriesService;
import com.iretailer.report.service.DevicesService;
import com.iretailer.report.service.FaceService;
import com.iretailer.report.util.GetId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;

/**
 * @Auther: xjw
 * @Date: 2019/8/8 0008 21:02
 * @Description:
 */
@Component
public class FaceInsert {

    private static final Logger log = LoggerFactory.getLogger(FaceInsert.class);

    @Autowired
    private FaceService faceService;
    @Autowired
    private DevicesService devicesService;
    @Autowired
    private DeviceCommon deviceCommon;
    @Autowired
    private CategoriesService categoriesService;
    @Autowired
    private FlowInsert flowInsert;

    public ResponeResultType insertFaceApi(FaceApi faceApi) {
        try {

            String deviceId = faceApi.getDeviceId();
            log.error(" faceApi is ture |  {} | {}  ", deviceId, faceApi.getIpAddress());
            Device device = devicesService.selectByDeviceId(deviceId);
            if (device != null) {
                Map<String, Categories> ageTypeMap = categoriesService.getAgeTypeMap();
                GenderAge genderAge = new GenderAge();
                String ageType = "";
                for (Map.Entry<String, Categories> item : ageTypeMap.entrySet()) {
                    Categories c = item.getValue();
                    int age = faceApi.getAge();
                    String[] ages = c.getData().split("-");
                    if (ages.length > 1) {
                        if (age >= Integer.valueOf(ages[0]) && age <= Integer.valueOf(ages[1])) {
                            ageType = c.getData();
                            break;
                        }
                    } else {
                        if (age >= Integer.valueOf(c.getData().replace("+", ""))) {
                            ageType = c.getData();
                            break;
                        }
                    }
                }
                genderAge.setAgeType(ageType);
                genderAge.setGender(faceApi.getGender());
                genderAge.setDate(faceApi.getTime().toLocalDate());
                genderAge.setDateTime(faceApi.getTime());
                genderAge.setDid(device.getId());
                genderAge.setImage(faceApi.getImg());
                genderAge.setPersonId(faceApi.getPersonId());
                String imageKey = device.getId() + "-" + GetId.LID();
                genderAge.setImageUrl(String.format("/report/%s/getFaceImage.action", imageKey));
                faceService.insertGenderAgeImage(genderAge, imageKey);
                log.error(" faceApi face is true |  {} ", deviceId);
                deviceCommon.updateDevice(device, faceApi.getTime(), faceApi.getMacAddress(), faceApi.getIpAddress(), faceApi.getDeviceId());
                return ResponeResultType.getOkRequest(ResponeResultType.CFLType.CLOSE);
            } else {
                log.error(" faceApi face deviceId not find |  {} ", deviceId);
                return ResponeResultType.getBadRequest(ResponeResultType.CFLType.CLOSE);
            }

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponeResultType.getBadRequest(ResponeResultType.CFLType.CLOSE);
        }
    }

    public ResponeResultType insertHorizon(HorizonModel horizonModel) {
        try {
            Map<String, Categories> ageTypeMap = categoriesService.getAgeTypeMap();
            String deviceId = horizonModel.getProperties().getDeviceId();
            log.error(" horizon is true |  {} | {}  ", deviceId, horizonModel.getProperties().getIPv4Address());
            Properties properties = horizonModel.getProperties();

            SmartData smartData = horizonModel.getSmartData();
            if (smartData != null) {
                Device device = devicesService.selectByDeviceId(deviceId);
                if (device != null) {
                    // 抓拍的照片
                    Face face = smartData.getFace();
                    if (face != null) {
                        insertFace(device.getId(), face, ageTypeMap);
                        log.error(" horizon face is true |  {} ", deviceId);
                    }
                    // 对比底度照片
//                    Feature feature = smartData.getFeature();
//                    if (feature != null) {
//                        insertFeatrue(device.getId(), feature);
//                    }
                    deviceCommon.updateDevice(device, LocalDateTime.ofInstant(Instant.ofEpochMilli(properties.getTransmitTime()),ZoneId.systemDefault()),
                            properties.getMacAddress(), properties.getIPv4Address(), properties.getSerialNumber());
                } else {
                    log.error(" horizon face deviceId not find |  {} ", deviceId);
                    return ResponeResultType.getBadRequest(ResponeResultType.CFLType.CLOSE);
                }
                // 客流统计数据
                FlowStats flowStats = smartData.getFlowStats();
                if (flowStats != null) {
                    PassengerFlowModel pfm = new PassengerFlowModel();
                    Properties p = horizonModel.getProperties();
                    pfm.setDeviceId(p.getDeviceId());
                    pfm.setDeviceName(p.getDeviceName());
                    pfm.setMacAddress(p.getMacAddress());
                    pfm.setIpAddress(p.getIPv4Address());
                    pfm.setDeviceType("horizon");
                    pfm.setSerialNumber(p.getSerialNumber());
                    InOutMetric inOutMetric = new InOutMetric();
                    inOutMetric.setZone(String.valueOf(flowStats.getLineType()));
//                    LocalDateTime endDateTime = LocalDateTime.ofEpochSecond(flowStats.getTimeStamp(), 0, OffsetDateTime.now().getOffset());
                    LocalDateTime endDateTime = flowStats.getDateTime();
                    LocalDateTime startDateTime = endDateTime.minusSeconds(flowStats.getInterval());
                    inOutMetric.setDate(startDateTime.toLocalDate());
                    inOutMetric.setStartTime(startDateTime.toLocalTime());
                    inOutMetric.setEndTime(endDateTime.toLocalTime());
                    inOutMetric.setExit(flowStats.getOutNumber());
                    inOutMetric.setEnter(flowStats.getInNumber());
                    pfm.setInOutMetrics(Collections.singletonList(inOutMetric));
                    log.error("------horizon deviceId {} flow --- {} {}", device.getDeviceId(), startDateTime, endDateTime);
                    flowInsert.analysisCommon(pfm);
                } else {
                    log.error("------horizon deviceId {} flow is null", device.getDeviceId());
                }
            }
            return ResponeResultType.getOkRequest(ResponeResultType.CFLType.CLOSE);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return ResponeResultType.getBadRequest(ResponeResultType.CFLType.CLOSE);
        }

    }

    public boolean insertFace(Long did, Face face, Map<String, Categories> ageTypeMap) {
        GenderAge genderAge = new GenderAge();
        Categories ageType = ageTypeMap.get(String.valueOf(face.getAge()));
        if (ageType != null) {
            genderAge.setAgeType(ageType.getData());
        } else {
            genderAge.setAgeType("");
        }
        genderAge.setGender(face.getGender());
//        LocalDateTime dateTime = LocalDateTime.ofEpochSecond(face.getTimeStamp() / 1000, 0, OffsetDateTime.now().getOffset());
        LocalDateTime dateTime = face.getDateTime();
        genderAge.setDate(dateTime.toLocalDate());
        genderAge.setDateTime(dateTime);
        genderAge.setDid(did);
//        genderAge.setImage(String.format("%s%s", "data:image/png;base64,", face.getSnapShot()));
        genderAge.setImage(face.getSnapShot());
        genderAge.setPersonId(face.getPersonId());
        String imageKey = did + "-" + GetId.LID();
        genderAge.setImageUrl(String.format("/report/%s/getFaceImage.action", imageKey));
        log.error("--------- face -------- {}", dateTime);
        return faceService.insertGenderAgeImage(genderAge, imageKey);
    }


//    public boolean insertFeatrue(Long did, Feature feature) {
//        FaceMatch faceMatch = new FaceMatch();
//        faceMatch.setDataBaseId(feature.getDatabaseId());
//        faceMatch.setDid(did);
//        faceMatch.setName(feature.getName());
//        faceMatch.setMatchedId(feature.getMatchedId());
////        faceMatch.setMatchedImg(String.format("%s%s", "data:image/png;base64,", feature.getMatchedImg()));
//        faceMatch.setMatchedImg(feature.getMatchedImg());
//        LocalDateTime dateTime = LocalDateTime.ofEpochSecond(feature.getTimeStamp() / 1000, 0, OffsetDateTime.now().getOffset());
//        faceMatch.setDate(dateTime.toLocalDate());
//        faceMatch.setLastDataTime(dateTime);
//        log.error("--------- feature -------- {}", dateTime);
//        faceMatch.setPersonId(feature.getPersonId());
//        if (StringUtil.notEmpty(faceMatch.getName()) && StringUtil.notEmpty(faceMatch.getMatchedImg())) {
//            return faceService.insertFaceMatch(faceMatch);
//        } else {
//            log.error("-- feature error {}", JSON.toJSONString(feature));
//        }
//        return true;
//    }

}
